package com.dews.common.utils.file;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.dews.common.utils.bean.OssEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Objects;
import java.util.UUID;

/**
 * 上传OSS私有加密通用封装
 *
 * @author qingfeng
 * @version 1.0.0
 * @date 2023/6/8
 */
@Slf4j
public class FileOssUtils {

    /**
     * 上传文件至阿里云OSS， 基于文件对象方式上传
     *
     * @param file 文件对象
     * @param filePath 文件在OSS上的文件夹路径  例如 attr/file
     * @return
     * @throws IOException
     */
    public static String upload(File file,
                                String filePath,
                                OssEntity ossEntity) throws Exception {
        if (Objects.isNull(file)) {
            log.error("传输异常，文件对象File为空！");
            throw new Exception("传输异常，文件对象File为空！");
        }

        //文件名：uuid.扩展名  去掉-
        String fileName = UUID.randomUUID().toString().replace("-", "");
        // 例如 task/file/737723748891-外包任务导出.xlsx
        String folder = filePath + "/" + fileName+"-"+file.getName();

        // 创建OSSClient实例。
        OSS ossClient = getOssClient(ossEntity.getEndpoint(), ossEntity.getAccessKeyId(), ossEntity.getSecret());

        try {
            // 执行上传操作
            ossClient.putObject(new PutObjectRequest(ossEntity.getBucket(), folder, new FileInputStream(file)));
            //返回url地址
            return "https://"
                    + ossEntity.getBucket()
                    + "."
                    + ossEntity.getEndpoint()
                    + "/"
                    + folder;

        } catch (OSSException e) {
            log.info("Failed to upload file: ", e);
            throw new RuntimeException(e);
        } catch (ClientException e) {
            log.info("获取阿里云OSS客户端失败: ", e);
            throw new RuntimeException(e);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
    /**
     * 上传文件至阿里云OSS，基于MultipartFile对象上传
     *
     * @param file 文件对象
     * @param filePath 文件在OSS上的文件夹路径  例如 attr/file
     * @return
     * @throws IOException
     */
    public static String upload(MultipartFile file,
                                String filePath,
                                OssEntity ossEntity) throws Exception {
        if (Objects.isNull(file)) {
            log.error("传输异常，文件对象MultipartFile为空！");
            throw new Exception("传输异常，文件对象MultipartFile为空！");
        }

        //文件名：uuid.扩展名  去掉-
        String fileName = UUID.randomUUID().toString().replace("-", "");
        String fileExtension = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String folder = filePath + "/" + fileName + fileExtension;

        // 创建OSSClient实例。
        OSS ossClient = getOssClient(ossEntity.getEndpoint(), ossEntity.getAccessKeyId(), ossEntity.getSecret());

        try {
            // 执行上传操作
            ossClient.putObject(
                    new PutObjectRequest(
                            ossEntity.getBucket(),
                            folder,
                            file.getInputStream()
                    )
            );

            //返回url地址
            return "https://"
                    + ossEntity.getBucket()
                    + "."
                    + ossEntity.getEndpoint()
                    + "/"
                    + folder;

        } catch (OSSException e) {
            log.info("Failed to upload file: ", e);
            throw new RuntimeException(e);
        } catch (ClientException e) {
            log.info("获取阿里云OSS客户端失败: ", e);
            throw new RuntimeException(e);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    private static OSS getOssClient(String endpoint, String accessKeyId, String secret) {
        return new OSSClientBuilder().build(endpoint, accessKeyId, secret);
    }


    public static void deleteFile(OssEntity ossEntity, String fileName) {
        //判断oss实例是否存在：如果不存在则创建，如果存在则获取
        OSS ossClient = getOssClient(ossEntity.getEndpoint(), ossEntity.getAccessKeyId(), ossEntity.getSecret());
        // 删除文件。
        ossClient.deleteObject(ossEntity.getBucket(), fileName);
        // 关闭OSSClient。
        ossClient.shutdown();
    }
}
